package com.ecology.num;

import java.util.*;

/**
 * 两数之和
 * 给定一个数组和一个目标值，在数组中找到相加等于目标值的2个数字，
 * 并输出角标，同一个角标的数字只能使用一次
 */
public class TwoNumTotal {
    /**
     * @see com.ecology.str.TestTwoNumTotal#test_two_num_total()
     */
    public static int[] twoNumTotal(int[] arr, int target) {
//        return withDoubleFor(arr, target);
        return withHashMap(arr, target);
    }

    private static int[] withHashMap(int[] arr, int target) {
//O(n)
        int res[] = new int[2];
        if (null == arr || arr.length < 1) {
            return res;
        }
        Map<Integer, List<Integer>> cacheMap = new HashMap<>();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > target) {
                continue;
            }
            int next = target - arr[i];
            if (cacheMap.containsKey(next)) {
                List<Integer> integers = cacheMap.get(next);
                for (Integer index2 : integers) {
                    if (i != index2) {
                        res[0] = i > index2?index2:i;
                        res[1] = i > index2?i:index2;
                        break;
                    }
                }
            }
            if (!cacheMap.containsKey(arr[i])) {
                ArrayList<Integer> objects = new ArrayList<>();
                objects.add(i);
                cacheMap.put(arr[i], objects);
            } else {
                cacheMap.get(arr[i]).add(i);
            }
        }
        return res;
    }
    private static int[] withDoubleFor(int[] arr, int target) {
//O(n^2)
        int res[] = new int[2];
        if (null == arr || arr.length < 1) {
            return res;
        }
        int len = arr.length;
        outer:for (int i = 0; i < len; i++) {
            int iVal = arr[i];
            for (int j = i + 1; j < len; j++) {
                int jVal = arr[j];
                if (iVal + jVal == target) {
                    res[0] = i;
                    res[1] = j;
                    break outer;
                }
            }
        }
        return res;
    }
}
